The namegen5 website.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

192 lines
4.7 KiB

<script context="module">
export function preload({params}) {
return this.fetch(`${params.name}.json`).then(r => r.json()).then(({name, collection, error}) => {
return { name, collection };
});
}
</script>
<script>
import { onMount } from "svelte";
import capitalize from "capitalize";
import Page from "../components/Page.svelte";
import Selector from "../components/Selector.svelte";
export let name;
export let collection;
/** @type {import("../rust/namegen-wasm").default} */
let generator = null;
let selectedSuffix = "";
let selectedFormat = "";
let generatedFormat = "";
let generatedSuffix = "";
let result = ""
let failed = false;
let buffer = [];
let formats = [];
let suffixes = [];
let loaded = "";
let mounted = false;
function reload() {
loaded = name.name;
import("../rust/namegen-wasm").then(({load, default: NameGenerator}) => {
return load().then(() => {
console.log("Setting up", name.name);
generator = new NameGenerator(name.data);
})
}).catch(() => {
failed = true;
}).finally(() => {
loaded = name.name;
})
}
function generate() {
if (loaded !== name.name) {
return;
}
let format = `${selectedFormat}:${selectedSuffix}`;
if (!name.data.formats.find(f => f.name === format)) {
format = selectedFormat;
}
if (!name.data.formats.find(f => f.name === format)) {
return;
}
if (generator !== null) {
if (buffer.length === 0) {
console.time("Generate 64 names");
buffer = generator.generateMany(format, 64);
console.timeEnd("Generate 64 names");
}
result = buffer.pop();
} else {
result = name.examples[format][Math.floor(Math.random() * name.examples[format].length)]
}
generatedFormat = selectedFormat;
generatedSuffix = selectedSuffix;
}
onMount(() => {
mounted = true;
})
$: {
if (mounted && loaded !== name.name) {
generator = null;
buffer = [];
generatedFormat = "";
generatedSuffix = "";
selectedFormat = "";
selectedSuffix = "";
reload();
}
}
$: {
if (mounted && (selectedFormat !== generatedFormat || selectedSuffix !== generatedSuffix)) {
buffer = [];
generate();
}
}
$: {
const formatNames = name.data.formats.map(f => f.name.split(":")[0]).filter((f, i, a) => !a.slice(0, i).includes(f));
const suffixNames = name.data.formats.map(s => s.name.split(":")[1]).filter(s => s).filter((s, i, a) => !a.slice(0, i).includes(s));
const formatLabels = formatNames.map(n => name.metadata[`formatLabel_${n}`] || n.split("_").map(t => capitalize(t)).join(" "));
const suffixLabels = suffixNames.map(n => name.metadata[`formatSuffixLabel_${n}`] || n.split("_").map(t => capitalize(t)).join(" "));
formats = formatNames.map((n, i) => ({value: n, text: formatLabels[i]}));
suffixes = suffixNames.map((n, i) => ({value: n, text: suffixLabels[i]}));
}
</script>
<svelte:head>
<title>{name.metadata.name} - Namegen 5</title>
</svelte:head>
<Page collection={collection} selected={name.name}>
<div class="name">
<h1>{name.metadata.name}</h1>
<div class="cateogry">{name.metadata.category}</div>
<div class="description">{name.metadata.description || ""}</div>
<div style="color: {name.metadata.color || "#eeeeee"}" class:long={result.length > 25} class="result">{result}</div>
{#if (failed)}
<div class="failed">Your browser does not support Webassembly, the generator will only pick one out of 30 examples.</div>
{/if}
{#if suffixes.length > 0}
<Selector color={name.metadata.color} bgcolor={name.metadata.bgcolor} label={name.metadata.formatSuffixType} options={suffixes} bind:value={selectedSuffix} />
{/if}
<Selector color={name.metadata.color} bgcolor={name.metadata.bgcolor} label="Format" prefer="full_" options={formats} bind:value={selectedFormat} />
<button disabled={(loaded !== name.name) && !failed} on:click={generate}>Generate</button>
<div class="footnote">{name.metadata.footnote || ""}</div>
</div>
</Page>
<style>
h1 {
text-align: center;
margin-bottom: 0;
line-height: 1em;
}
div.failed {
color: #fc1;
font-size: 0.9em;
}
div.footnote {
font-size: 0.9em;
color: #555;
margin-top: 2em;
}
div.footnote:empty {
display: none;
}
div.cateogry {
font-size: 0.75em;
opacity: 0.75;
margin-bottom: 1em;
}
div.result {
border: 1px solid #000;
border-radius: 0.5em;
background-color: #333;
padding: 0.5em 0;
color: #eee;
text-align: center;
font-size: 1.5em;
min-height: 1.5em;
}
div.result.long {
font-size: 1.25em;
padding: 0.75em 0;
}
button {
background: #333;
outline: none;
border: 1px solid #000;
color: #ccc;
padding: 0.25em 1ch;
margin: 1.5em 0 0.5em 0;
font-size: 1.5em;
}
button:hover {
color: #fff;
}
button:active {
background: #444;
}
</style>